import React, { useEffect, useState } from 'react'
import Taro, { FC, getCurrentInstance } from "@tarojs/taro"
import { View, Button, Image, Text, ButtonProps, ITouchEvent } from "@tarojs/components"
import { combineLatest, of, Subject, Subscription } from 'rxjs';
import { debounceTime, filter, map, switchMap } from 'rxjs/operators';
import { getLogger } from '@/utils/log';

import ChannelStyle from '@@/channel/channelStyle'
import { useAuthFacade } from "@/hooks/useAuthFacade";
import { useMsgFacade } from '@/hooks/useMsgFacade';
import './index.scss'

//定义组件入参
type Props = {
  //点击按钮过来
  clicked: boolean;
  //接收父组件改变clicked的Set方法,用来改变父组件clicked的值
  setClicked: (val: boolean) => void;
  //来源页面
  fromUrl?: string;
  //跳转页面
  goUrl?: string;
  //清空或者调整跳转页面
  setGoUrl?: (val: string) => void;
  //回调方法
  callback?: () => void;
};

export const Login: FC<Props> = ({ fromUrl, goUrl, clicked, setClicked, setGoUrl, callback }) => {
  //FIXME: 由于rxjs的调用层级关系，内层的错误会抛出到最外层进行捕捉，所以外层会打印记录所有内层的异常信息，考虑不在内层进行日志记录
  const logger = getLogger("/components/loginPopup");

  const initSubject = () => new Subject<ButtonProps.onGetPhoneNumberEventDetail>();
  // 初始化按钮接收参数subject
  const [emitter, setEmitter] = useState(initSubject);

  //用不到的变量不用写
  const [authFacade, loginStatus] = useAuthFacade();
  const [msgFacade] = useMsgFacade();

  //隐藏弹窗，清空数据
  const handleClose = (e: ITouchEvent) => {
    e.stopPropagation()
    setClicked(false);
    setGoUrl && setGoUrl("");

    const { router } = getCurrentInstance();
    //控制底部tab显示/隐藏
    if (router && router.path && (router.path === '/pages/index/index' || router.path === '/pages/my/index/index')) {
      Taro.showTabBar();
    }
  }

  //跳转服务协议
  const toServiceAgreement = () => {
    Taro.navigateTo({
      // url: '/pages/liveRoom/ServiceAgreement/index',
      url: '/subPages/liveRoom/ServiceAgreement/index',
    })
  }

  //第一个useEffect，不需要监听任何值，只执行一次
  const onceEffect = () => {
    //第一次进入需要授权的页面，进行登录态刷新
    const subscriptions: Subscription[] = [
      authFacade.checkLogin()
        .subscribe(),

      //设置loading状态避免重复请求，因为登陆组件不是单例，多实例状态下会重复触发请求
      combineLatest([authFacade.loginStatus$, msgFacade.isSDKReady$, msgFacade.isLoading$])
        .pipe(
          debounceTime(500),
          //auth store刷新后才需要重新登录IM，isLoading用于避免重复登陆
          filter(([isLogin, isSDKReady, isLoading]) => isLogin && !isSDKReady && !isLoading),
          switchMap(msgFacade.loginIM)
        )
        .subscribe(),
    ];

    return subscriptions;
  }

  useEffect(() => {
    const subscriptions = onceEffect();

    //页面销毁时也销毁所有订阅，防止内存泄漏
    return () => { subscriptions.map(sub => sub.unsubscribe()) };
  }, []);

  //第二个useEffect，需要监听某个值，变化后重新运行
  useEffect(() => {
    //由点击授权按钮触发的流
    const subscriptions: Subscription[] = [
      combineLatest([emitter.asObservable(), authFacade.jsCode$])
        .pipe(
          //等待合法的js_code
          filter(([, jsCode]) => !!jsCode.code && jsCode.expires > new Date().getTime() && clicked),
          map(([details]) => details),
          //接收按钮点击的参数
          switchMap(authFacade.wxBindPhone)
        )
        .subscribe(
          {
            next: () => console.log,
            error: err => {
              logger.ERROR("authFacade.wxBindPhone错误信息", err);
              //重新创建一个可以传值的subject，因为之前的已经complete,不能再传值
              setEmitter(initSubject);
            }
          }
        ),
    ];

    //页面销毁时也销毁所有订阅，防止内存泄漏
    return () => { subscriptions.map(sub => sub.unsubscribe()) };
  }, [emitter, clicked]);

  //点击触发的流
  useEffect(() => {
    const subscriptions: Subscription[] = [
      //这个观察者流用于获取js_code
      of(1)
        .pipe(
          filter(() => clicked),
          switchMap(authFacade.wxLogin)
        )
        .subscribe(),

      //这个观察者流用于隐藏显示底部tab，以及控制跳转页面
      authFacade.loginStatus$
        .pipe(
          filter(() => clicked)
        )
        .subscribe(
          isLogin => {
            const { router } = getCurrentInstance();
            //控制底部tab显示/隐藏
            if (router && router.path && (router.path === '/pages/index/index' || router.path === '/pages/my/index/index')) {
              if (!isLogin) {
                Taro.hideTabBar()
              } else {
                Taro.showTabBar()
              }
            }

            if (isLogin) {
              //充值弹窗状态
              setClicked(false);

              //如果已经登录则直接跳转
              if (goUrl) {
                Taro.navigateTo({
                  url: goUrl,
                  success: () => setGoUrl && setGoUrl("")   //清理跳转Url
                })
              }
            }
          }
        )
    ]

    return () => { subscriptions.map(sub => sub.unsubscribe()) };
  }, [clicked])

  return (
    <View className='login_box' style={{ display: loginStatus || !clicked ? "none" : "block", zIndex: loginStatus || !clicked ? -1 : 999 }}>
      <View className='box'>
        <View className='close' onClick={handleClose}>
          <Image src='https://leconglive-wxapp-1301839528.file.myqcloud.com/wxIcon/close.png' className='close_img'></Image>
        </View>
        <View className='login'><Text className='title'>登录授权</Text></View>
        <View className='login_content'>
          <Text className='login_ct'>相关功能需要登陆后才可以使用，请在接下来得</Text>
          <Text className='login_ct'>授权中点击“允许”</Text>
        </View>
        <Button className='allow' open-type='getPhoneNumber' onGetPhoneNumber={e => emitter.next(e.detail)} ><Text>允许</Text></Button>
        <View className='login_agree'>
          <Text className='agree'>确认即同意</Text>
          <Text className='agreement' onClick={toServiceAgreement}>《{ChannelStyle.appName}LIVE用户服务协议》</Text>
        </View>
      </View>
    </View>
  )
}

export default React.memo(Login)